

/**
 *	Base Class
 */
Jx.Class = (function Class(){

	return Jx.Class.__run_ClassConstruct( this, arguments );

});

/**
 *	Base Class properties
 */
Jx.assign(Jx.Class.prototype, {

	destroyed: true,

	$name: function(){

		return this.constructor.$name;

	},

	$super: function(args){

		var method = arguments.callee.caller,

			override = method && method.$super;

		if (!method || !override){

			throw new Error(

				!override ?

					'Class has no superclass of this method'

					:

					'this method cannot be used outside the class method'

			);

			return void(0);

		}

		return override.apply(this, args || []);

	},

	$overriden: function($args){

		var method = arguments.callee.caller,

			override = method && method.$overriden;

		if (!method || !override){

			throw new Error(

				!override ?

					'Class has no override of this method'

					:

					'this method cannot be used outside the class method'

			);

			return void(0);

		}

		return override.apply(this, args || []);

	},

	construct: function(){

		this.onConstruct.apply(this, arguments);

	},

	onConstruct: function(){ },

	onDestroy: function(){

		var J = Jx;

		if (J.isObject(this.$cache)){

			J.clearObject( this.$cache );

		}

	},

	destroy: function(){

		var J = Jx;

		if (!this.destroyed && !this.destroying){

			this.destroying = true;

			this.onDestroy();

			J.Class.__run_InstanceCallback( true, this, this.constructor );

			J.clearObject( this );

			this.destroyed = true;

		}

	}

});




/**
 * Base Class Static Properties and Methods
 *
 */
Jx.assign(Jx.Class, {

	$defaults: (function Cache(){}),

	$operator: (function(){

		function Operation(o){

			this.assignProperties( o );

			this.timeStarted = (new Date()).getTime();

		};

		var NIL = void(0);

		/* define defaults */
		Jx.assign( Operation.prototype, {

			method: 'unknown_method',

			name: 'unknown',

			value: NIL,

			oldValue: NIL,

			data: NIL,

			params: NIL,

			valid: true,

			applyData: false,

			returnValue: NIL,

			execBefore: false,

			execOn: true,

			execAfter: false,

			trace: false,

			assignProperties: function(o){

				var J = Jx;

				if (J.isObject(o)){

					J.assign(this, o);

				}

				return this;

			},

			destroy: function(){

				if (this.trace){

					function TRACE(){

						var fn = arguments.callee;

						console.log( fn.method + '() runtime: '+ (fn.ms/1000)+' seconds ');

						delete fn.ms;

						delete fn.method;

					}

					TRACE.ms = (new Date()).getTime() - this.timeStarted;

					TRACE.method = this.method;

					setTimeout( TRACE, 100 );

				}

				var J = Jx;

				J.clearObject(this.params);

				J.clearObject(this);

			}

		});

		return Operation;

	})(),

	toDeclare: [],

	__ref_ClassMap: {},

	__ref_NsMap: { '': {} },

	__ref_ClassDeclarationCallbacks: {},

	__ref_InstanceConstructCallbacks: {},

	__ref_InstanceDestructCallbacks: {},

	__ref_ClassDefinitionProcessors: {},

	__callback_tokenizer_TokensToNsStruct: function(token, obj, first, last){

		if (first){

			obj.tokens = [];

		}

		obj.tokens.push(token);

		if (last){

			var tokens = obj.tokens,

				len = tokens.length;

			obj.returnValue = {

				path: tokens.join('.'),

				ns: len > 1 ?

					tokens.slice(0, len - 1).join('.')

					:

					'',

				name: tokens[ len - 1 ]

			}

		}

	},

	__callback_tokenizer_TokensToNsObject: function(token, obj, first, last){

		var J = Jx,

			current = first ?

				J.GLOBAL

				:

				obj.returnValue,

			returned = J.isObject(current, false);

		if (returned){

			obj.returnValue = current[token];

		}

		return returned;

	},

	__callback_tokenizer_TokensToNsObjectIf: function(token, obj, first, last){

		if (first){

			obj.tokens = [];

		}

		var tokens = obj.tokens,

			map = this.__ref_NsMap,

			J = Jx,

			current = first ?

				J.GLOBAL

				:

				obj.returnValue,

			next = token in current ?

				current[token]

				:

				void(0),

			path = tokens.join('.'),

			mapped = !map.hasOwnProperty(path) ?

				(map[path] = {})

				:

				map[path];

		if (!J.isObject(next, false)){

			next = current[token] = {};

		}

		// update path
		if (!mapped.hasOwnProperty(token)){

			mapped[token] = next;

		}

		tokens.push(token);

		obj.returnValue = next;

		path = tokens.join('.');

		if (last && !map.hasOwnProperty(path)){

			map[ path ] = {};

		}

	},

	__callback_SetupDefinedHelpers: function(n, v, o){

		if (o.hasOwnProperty(n) && Jx.isString(v)){

			this.requires.push(v);

			this.helpers[n] = v;

		} else {

			delete o[n];

		}

	},

	__callback_DeclareClassHelpers: function(n, v, o){

		if (o.hasOwnProperty(n)){

			this.prototype[ '__' + n ] = Jx.Class.getInstance(v);

		}

	},

	__callback_ObjectHasOwnProperty: function(n, v, o){

		return !(this.has = o.hasOwnProperty(n));

	},

	__callback_PropertiesOverride: function(name, value, property){

		var Class = this,

			O = Object.prototype,

			Proto = Class.prototype,

			override;

		if (property.hasOwnProperty(name)){

			// method override
			if (O.toString.call(value) == '[object Function]'){

				if (name == 'constructor'){

					name = 'construct';

				}

				//-- bootstrap borrowed methods
				if (value.hasOwnProperty('$method')){

					var __caller__ = value;

					value = function(){

						return __caller__.apply(this, arguments);

					};

				}

				value.$method = name;

				if (name in Proto &&

					O.toString.call(override = Proto[name]) == '[object Function]'

				){

					//-- first override
					if (Class.firstOverride){

						value.$super = override;

					} else {

						if ('$super' in override){

							value.$super = override.$super;

						}

						value.$overriden = override;

					}

				}

			}

			Proto[ name ] = value;

		}

	},

	__callback_ClearOldInstance: function(n, v, o){

		if (o.hasOwnProperty(n) && n in this){

			delete this[n];

		}

	},

	__help_Capitalize: function(name){

		return name.length ?

			name.charAt(0).toUpperCase() + name.substring(1, name.length)

			:

			name;

	},

	__help_ObjectHasMethod: function(name, Class, hasOwn){

		var J = Jx,

			proto = J.isFunction(Class) ?

				Class.prototype

				:

				Class;

		return (

			hasOwn ?

				proto.hasOwnProperty(name)

				:

				name in proto

		) && J.isFunction(proto[name]);

	},

	__help_DefineMethodIf: function(name, SuperClass, properties, fn, fnProperties){

		var J = Jx;

		// apply if no exec method
		if (!this.__help_ObjectHasMethod(name, SuperClass) && !this.__help_ObjectHasMethod(name, properties, true)){

			properties[ name ] = fn;

			if (J.isObject(fnProperties)){

				J.assign(fn, fnProperties);

			}

			return fn;

		}

		return void(0);

	},

	__help_ObjectHasOwnProperty: function(obj){

		var ret = { has: false };

		Jx.each(obj, this.__callback_ObjectHasOwnProperty, ret);

		return ret.has;

	},

	__help_FormatActionValue: function(value, ignoreNames, cached){

		var defaults = {},

			newActions = [],

			J = Jx;

		if (J.isString(value)){

			value = [value];

		}

		//-- create defaults
		if (J.isArray(value)){

			for(var name, l = value.length; l--;){

				if (J.isString(name = value[l]) && name && ignoreNames.indexOf(name) == -1){

					newActions[l] = name;

					if (cached){

						defaults[ name ] = void(0);

					}

				} else {

					newActions.splice(l, 1);

				}

			}

		} else if (J.isObject(value)){

			J.each(value, function(n, v, o){

				if (o.hasOwnProperty(n) && n){

					//-- apply default
					if (this.cached){

						this.defaults[n] = v;

					}

					if (this.ignore.lastIndexOf(n) == -1){

						this.actions.push(n);

					}

				}


			}, { defaults: defaults, actions: newActions, ignore: ignoreNames, cached: cached });

		}

		return { defaults: defaults, actions: newActions};

	},

	__help_SetAndCascadeCallback: function(struct, value, access, args){

		var SuperStruct = struct.SuperStruct,

			callbacks = SuperStruct.hasOwnProperty(access) ?

				SuperStruct[access].slice(0)

				:

				[];

		if (Jx.isFunction(value)){

			callbacks.unshift(value);

		}

		// set
		struct[ access ] = callbacks;

		for(var l = callbacks.length; l--;){

			callbacks[l].apply(this, args);

		}

	},

	__help_SetInstanceCallbacks: function(destruct, struct, value){

		// inherit callback
		var SuperPath = struct.SuperStruct.path,

			allCallbacks = this[

				destruct ?

					'__ref_InstanceDestructCallbacks'

					:

					'__ref_InstanceConstructCallbacks'

			],

			myCallbacks = allCallbacks[struct.path] = [];

		if (allCallbacks.hasOwnProperty(SuperPath)){

			myCallbacks.push.apply(myCallbacks, allCallbacks[SuperPath]);

		}

		if (Jx.isFunction(value)){

			myCallbacks[

				destruct ?

					'push'

					:

					'unshift'

			](value);

		}

	},

	__run_ProcessStruct: function( process, struct, args ){

		if (!Jx.isArray(args)){

			args = [];

		}

		var processors = this.__ref_ClassDefinitionProcessors,

			def = struct.definition,

			properties = struct.properties,

			order;

		if (processors.hasOwnProperty(process)){

			processors = processors[process];

			order = processors._order;

			for(var name, value, pname, l = order.length; l--;){

				value = void(0);

				name = order[l];

				pname = '$' + name;

				if (def.hasOwnProperty(pname)){

					value = def[ pname ];

					//-- remove!!!
					if (properties.hasOwnProperty(pname)){

						delete properties[pname];

					}

				}

				processors[ name ].apply(this,

					args.concat([struct, value])

				);


			}

		}

	},

	__run_PathCallbacks: function( path ){

		var o = this.getStruct(path),

			allCallbacks = this.__ref_ClassDeclarationCallbacks,

			Class, Super;

		if (o && allCallbacks.hasOwnProperty(path = o.path) && o.declared){

			Class = o.Class;

			Super = Class.$based;

			for(var callbacks = allCallbacks[path], l = callbacks.length; l--;){

				callbacks[l].call(this, Class, Super, o.instance);

				callbacks.splice(l, 1);

			}

		}

	},

	__run_Declarations: function(){

		var classes = this.toDeclare,

			map = this.__ref_ClassMap;

		for(var name, struct, l = classes.length; l--;){

			struct = this.getStruct( name = classes[l] );

			if (!struct){

				classes.splice(l, 1);

				continue;

			}

			if (this.canDeclare( name )){

				this.onDeclare(struct);

				classes.splice(l, 1);

				//-- reset
				l = classes.length;

			}

		}

	},

	__run_TokenizePath: function(name, fn, scope){

		scope = scope || this;

		var NIL = void(0);

		if (Jx.isString(name)){

			for(var dot, chr, last, first = true, obj = {}, token = NIL, anchor = 0, c=0, l=name.length; c<l; c++){

				chr = name.charAt(c);

				dot = chr == '.';

				last = (c+1) == l;

				if (dot || last){

					token = name.substring(anchor, dot ? c : c+1);

				}

				if (token){

					anchor = c+1;

					if (fn.call(scope, token, obj, first, last) === false){

						return NIL;

						break;

					}

					if (first){

						first = false;

					}

					token = NIL;

				}

			}

			return first ?

				NIL

				:

				obj.hasOwnProperty('returnValue') ?

					obj.returnValue

					:

					obj;

		}

		return NIL;

	},

	__run_InstanceAction: function(instance, args, obj){

		var NIL = void(0),

			J = Jx,

			__returnValue__ = NIL,

			method = arguments.callee.caller,

			getter = method.$getter,

			params, o;

		if (!instance.destroyed){

			o = new (J.Class.$operator)({

				method: method.$action_name,

				name: method.$data_access,

				oldValue: getter in instance ?

					instance[ getter ]()

					:

					NIL,

				data: instance.$cache,

				params: params = Array.prototype.slice.call(args, 0),

				returnValue: instance

			});

			/* assign object */
			o.assignProperties( obj );

			params.unshift(o);

			instance[ method.$action_validate ].apply(instance, params);

			if (o.valid && !instance.destroyed){

				if (o.execBefore){

					instance[ method.$action_before ].apply(instance, params);

				}

				if (o.execOn && !instance.destroyed){

					instance[ method.$action_on ].apply(instance, params);

				}

				if (o.execAfter && !instance.destroyed){

					instance[ method.$action_after ].apply(instance, params);

				}

			}

			__returnValue__ = o.returnValue;

			/* cleanup */
			o.destroy();

		}

		return __returnValue__;

	},

	__run_InstanceCallback: function(destruct, instance, Class){

		var allCallbacks = this[

				destruct ?

					'__ref_InstanceDestructCallbacks'

					:

					'__ref_InstanceConstructCallbacks'

			],

			path = Class.$name;

		if (allCallbacks.hasOwnProperty(path)){

			for(var callbacks = allCallbacks[path], l = callbacks.length; l--;){

				callbacks[l].call(instance, Class);

			}

		}

	},

	__run_ClassConstruct: function(instance, args){

		var Class = arguments.callee.caller,

			Cache = Class.$defaults;

		if (!(instance instanceof Class)){

			var Temp = new Function();

			Temp.prototype = Class.prototype;

			instance = new Temp();

		}

		instance.destroyed = false;

		instance.$cache = new Cache();

		this.__run_InstanceCallback( false, instance, Class, Array.prototype.slice.call(args, 0) );

		instance.construct.apply(instance, args);

		return instance;

	},



	onDeclare: function(struct){

		// postprocess declared classes properties

		var newlyDeclared = !struct.declared;

		if (newlyDeclared){

			this.__run_ProcessStruct('pre', struct);

			this.__run_ProcessStruct('declare', struct);

			this.__run_ProcessStruct('post', struct);

		}

		//-- publicize
		if (struct.publicize){

			this.onLinkStruct( struct );

		}

		this.__run_PathCallbacks(struct.path);

		//-- create category
		if (newlyDeclared && struct.category){

			this.__run_PathCallbacks( struct.category );

		}

	},

	onLinkStruct: function(struct){

		var o = this.createNamespace(struct.ns),

			nsMap = this.__ref_NsMap,

			name = struct.name,

			path = struct.path,

			J = Jx,

			oldMapped, oldInstance, nsMapped, instance;

		if (o){

			nsMapped = nsMap[ struct.ns ];

			oldMapped = nsMap.hasOwnProperty(path) ?

				nsMap[path]

				:

				void(0);

			oldInstance = nsMapped.hasOwnProperty(name) ?

				nsMapped[name]

				:

				void(0);

			// set instance
			instance = o[name] = nsMapped[name] = struct.instance;

			// remove/replace instance
			if (oldMapped){

				// clear old instance
				if (oldInstance){

					J.each(oldMapped, this.__callback_ClearOldInstance, oldInstance);

				}

				// link instances
				J.assignOwned(instance, oldMapped);

			}

		}

	},

	getStruct: function(name, resolve){

		var o = this.getNsStruct(name),

			map = this.__ref_ClassMap,

			found = void(0), path;

		//-- get main
		if (o && map.hasOwnProperty(path = o.path)){

			found = map[ path ];

			if (resolve !== false && Jx.isObject(found.link)){

				found = found.link;

			}

		}

		return found;

	},

	getNsObject: function(path){

		var o = this.__run_TokenizePath(path, this.__callback_tokenizer_TokensToNsObject, this);

		return Jx.isObject(o, false) ?

			o

			:

			void(0);

	},

	getNsStruct: function(path){

		var o = this.__run_TokenizePath(path, this.__callback_tokenizer_TokensToNsStruct, this);

		return o.path == path ?

			o

			:

			void(0);

	},

	getInstance: function(name){

		var struct = this.getStruct(name);

		return struct && struct.declared ?

			struct.instance

			:

			void(0);

	},

	getClass: function(name){

		var struct = this.getStruct(name);

		return struct && struct.declared ?

			struct.Class

			:

			void(0);

	},

	resolveClass: function(Class){

		var J = Jx;

		return J.isString(Class) ?

			this.getClass(Class)

			:

			J.isFunction(Class) ?

				Class

				:

				void(0);

	},

	canDeclare: function(name){

		var o = this.getStruct(name),

			req;

		if (o && !o.declared){

			req = o.requires;

			//-- check required
			for(var rname, l = req.length; l--;){

				if ( this.isDeclared(rname = req[l]) ){

					req.splice(l, 1);

				} else {

					break;

				}

			}

			return req.length == 0;

		}

		return false;

	},

	isDeclared: function(name){

		var o = this.getStruct(name);

		return !!o && o.declared;

	},

	setCallback: function(path, fn){

		var allCallbacks = this.__ref_ClassDeclarationCallbacks,

			o = this.getNsStruct(path),

			struct, callbacks;

		if (o && Jx.isFunction(fn)){

			callbacks = allCallbacks.hasOwnProperty(path = o.path) ?

				allCallbacks[ path ]

				:

				(allCallbacks[ path ] = []);

			callbacks.unshift(fn);

			//-- apply callback to declared class
			if ( this.isDeclared(path) ){

				this.__run_PathCallbacks(path);

			}

		}

	},

	setProcessor: function(process, name, fn){

		var processors = this.__ref_ClassDefinitionProcessors,

			J = Jx,

			applyOrder, group;

		if (J.isString(name) && J.isString(process) && J.isFunction(fn)){

			if (!processors.hasOwnProperty(process)){

				processors[process] = { '_order': [] };

			}

			group = processors[process];

			applyOrder = !group.hasOwnProperty(name);

			group[name] = fn;

			if (applyOrder){

				group._order.unshift(name);

			}

		}

		return this;

	},

	createNamespace: function(ns){

		return ns == '' ?

			Jx.GLOBAL

			:

			this.__run_TokenizePath(ns, this.__callback_tokenizer_TokensToNsObjectIf, this);

	},

	createDefinition: function(o, def){

		var J = Jx,

			struct = J.assign({

				singleton: false,

				declared: false,

				Class: void(0),

				instance: void(0),

				definition: def,

				properties: J.assign({}, def),

				requires: []

			}, o);

		this.__run_ProcessStruct('definition', struct );

		return struct;

	},

	declare: function(path, properties){

		var o = this.getNsStruct(path), struct;

		if (o){

			if (!Jx.isObject(properties)){

				properties = {};

			}

			struct = this.createDefinition(o, properties);

			this.toDeclare.push( o.path );

		}

		this.__run_Declarations();

	},

	declareNsObject: function(path){

		var o = this.getNsStruct(path),

			instance = o && this.getNsObject( o.path ),

			J = Jx,

			isFunction = J.isFunction(instance),

			struct;

		if (J.isObject(instance) || isFunction){

			struct = this.createDefinition(o, {});

			struct.instance = instance;

			struct.Class = (struct.singleton = !isFunction) ?

				instance.constructor

				:

				instance;

			struct.declared = true;

			this.onDeclare(struct);

			this.__run_Declarations();

		}

	},


	declareCategory: function(path, properties){

		var J = Jx;

		properties = J.assignIf({

			$category: true

		}, J.isObject(properties) ? properties : {});

		return this.declare(path, properties);

	},

	instantiate: function(name, args){

		var Class = this.resolveClass(name);

		return Class ?

			this.instiateClass(Class, args)

			:

			void(0);

	},

	instiateClass: function(Class, args){

		var instance = void(0),

			Temp;

		if (Jx.isFunction(Class)){

			args = args || [];

			(Temp = new Function()).prototype = Class.prototype;

			instance = new Temp();

			//-- exec constructor
			instance.constructor.apply( instance, args );

		}

		return instance;

	},

	override: function( properties ){

		var J = Jx;

		if (properties instanceof Object){

			J.each( properties, J.Class.__callback_PropertiesOverride, this );

		}

		return this;

	},

	extend: function( additional ){

		var Super = this,

			Temp, BasedProto;

		BasedProto = (Temp = function(){}).prototype = Super.prototype;

		function Class(){

			return Jx.Class.__run_ClassConstruct( this, arguments );

		}

		Class.prototype = new Temp();

		Class.$based = BasedProto;

		Class.$method = 'constructor';

		Class.extend = this.extend;

		Class.override = this.override;

		if (additional){

			Class.firstOverride = true;

			Class.override(additional);

			delete Class.firstOverride;

		}

		Class.prototype.constructor = Class;

		return Class;

	}

});

/**
 *	Definition Processors
 */

Jx.Class.setProcessor('definition', 'category', function(struct, value){

	var J = Jx;

	struct.link = false;

	struct.category = false;

	struct.publicize = true;

	struct.categoryPath = '';

	if (value === true){

		value = struct.path;

		J.assign(struct, this.getNsStruct(value));

		struct.publicize = false;

		struct.categoryPath = struct.path;

	} else if (J.isString(value) && value){

		struct.categoryPath = struct.category = this.getNsStruct(value).path;

	}

	this.__ref_ClassMap[ struct.path ] = struct;

});


Jx.Class.setProcessor('definition', 'extend', function(struct, value){

	var J = Jx;

	value = value && J.isString(value) ?

		value

		:

		'Jx.Class';

	//-- add to require
	struct.requires.push(

		struct.extend = value

	);

	J.assign(struct, {

		actions: [],

		accessors: [],

		defaults: {}

	});

});

Jx.Class.setProcessor('definition', 'requires', function(struct, value){

	var J = Jx;

	if (J.isString(value)){

		value = [value];

	}

	if (J.isArray(value)){

		for(var path, l = value.length; l--;){

			if (Jx.isString(path = value[l]) && path){

				struct.requires.push(path);

			}

		}

	}

});

Jx.Class.setProcessor('definition', 'helpers', function(struct, value){

	var J = Jx;

	struct.helpers = {};

	if (J.isObject(value)){

		J.each( value, this.__callback_SetupDefinedHelpers, struct);

	}

});

Jx.Class.setProcessor('definition', 'singleton', function(struct, value){

	struct.singleton = Jx.isBoolean(value) ? value : false;

});


/**
 *	Pre Declaration Processors
 */
Jx.Class.setProcessor('pre', 'extend', function(struct, value){

	var SuperStruct = this.getStruct( struct.extend ),

		actions = SuperStruct.actions;

	// predefine struct from extended class
	struct.SuperStruct = SuperStruct;


});

Jx.Class.setProcessor('pre', 'accessors', function(struct, value){

	var SuperStruct = struct.SuperStruct,

		SuperClass = SuperStruct.Class,

		properties = struct.properties,

		found = this.__help_FormatActionValue(value, SuperStruct.accessors, true),

		J = Jx;

	//-- recreate function if no accessors or actions in struct

	// apply defaults
	J.assign(struct.defaults, found.defaults);

	// apply names
	struct.accessors.push.apply( struct.accessors, found.actions);

	// create getters
	for(var fn, name, ucname, setter, newAccessors = struct.accessors, newActions = struct.actions, currentActions = SuperStruct.actions, l = newAccessors.length; l--;){

		ucname = this.__help_Capitalize(

			name = newAccessors[l]

		);

		//-- setter onSet
		this.__help_DefineMethodIf( 'onSet'+ucname, SuperClass, properties, function Setter_On(operation){

			if (operation.applyData){

				operation.data[ operation.name ] = operation.value;

			}

		});

		//-- create getter
		this.__help_DefineMethodIf( 'get'+ucname, SuperClass, properties, function Getter(){

			var fn = arguments.callee,

				J = Jx,

				access = fn.$data_access,

				data = this.$cache,

				__returnValue__ = void(0),

				params;

			if (!this.destroyed){

				(params = [

					J.isPropertyEnumerable(access, data) ?

						data[access]

						:

						void(0)

				]).push.apply(params, Array.prototype.slice.call(arguments, 0));

				__returnValue__ = this[ fn.$getter_format ].apply( this, params );

				J.clearObject(params);

			}

			return __returnValue__;

		}, { $data_access: name, $getter_format: 'formatGet'+ucname });


		//-- create setter
		this.__help_DefineMethodIf( setter = 'set'+ucname, SuperClass, properties, function Setter(value){

			return Jx.Class.__run_InstanceAction( this, arguments, {

				applyData: true,

				value: value

			});

		}, {

			$data_access: name,
			$action_name: setter,
			$getter: 'get'+ucname,
			$action_validate: 'allowSet'+ucname,
			$action_before: 'onBeforeSet'+ucname,
			$action_on: 'onSet'+ucname,
			$action_after: 'onAfterSet'+ucname

		});

		// create getter format
		this.__help_DefineMethodIf( 'formatGet'+ucname, SuperClass, properties, function Getter_Format( value ){

			return value;

		});


		// push to action if setter is not defined
		if (currentActions.indexOf(setter) == -1){

			newActions[l] = setter;

		} else {

			newActions.splice(l, 1);

		}

	}

	// insert superclass accessors for reference
	struct.accessors.unshift.apply( struct.accessors, SuperStruct.accessors);

});

Jx.Class.setProcessor('pre', 'actions', function(struct, value){

	var SuperStruct = struct.SuperStruct,

		SuperClass = SuperStruct.Class,

		properties = struct.properties,

		found = this.__help_FormatActionValue(value, SuperStruct.actions);


	// apply defaults
	Jx.assign(struct.defaults, found.defaults);

	// apply names
	struct.actions.push.apply( struct.actions, found.actions);

	// create actions
	for(var exec, ucname, actions = struct.actions, l = actions.length; l--;){

		ucname = this.__help_Capitalize(

			exec = actions[l]

		);

		// protected methods
		this.__help_DefineMethodIf( 'onBefore'+ucname, SuperClass, properties, function Action_Before(operation){

		});

		this.__help_DefineMethodIf( 'on'+ucname, SuperClass, properties, function Action_On(operation){
		});

		this.__help_DefineMethodIf( 'onAfter'+ucname, SuperClass, properties, function Action_On(operation){
		});

		// validate method
		this.__help_DefineMethodIf( 'allow'+ucname, SuperClass, properties, function Validate(operation){

			//-- toggle process here
			Jx.assign(operation, {

				execBefore: false,

				execOn: true,

				execAfter: false

			});

			return true;

		});

		// action
		this.__help_DefineMethodIf( exec, SuperClass, properties, function Action(){

			return Jx.Class.__run_InstanceAction( this, arguments );

		}, {

			$data_access: exec,
			$action_name: exec,
			$getter: 'get'+ucname,
			$action_validate: 'allow'+ucname,
			$action_before: 'onBefore'+ucname,
			$action_on: 'on'+ucname,
			$action_after: 'onAfter'+ucname

		});

	}

	// insert superclass actions for reference
	struct.actions.unshift.apply( struct.actions, SuperStruct.actions);

});

Jx.Class.setProcessor('pre', '$precallback', function(struct, value){

	this.__help_SetAndCascadeCallback(struct, value, 'precallback', [ struct.properties, struct.SuperStruct.Class.prototype, struct ]);

});

Jx.Class.setProcessor('pre', 'precallback', function(struct, value){

	if (Jx.isFunction(value)){

		value.call( struct.properties, struct.SuperStruct.Class.prototype );

	}

});

/**
 *	Declaration Processors
 */

Jx.Class.setProcessor('declare', 'extend', function(struct, value){

	// declare process
	var SuperClass = struct.SuperStruct.Class,

		Class = struct.Class = SuperClass.extend( struct.properties ),

		SuperDefaults = SuperClass.$defaults,

		defaults = struct.defaults;

	struct.declared = true;

	Class.$name = struct.path;

	//-- create cache class
	if (this.__help_ObjectHasOwnProperty(defaults)){

		function Cache(){};

		Jx.assign(Cache.prototype = new SuperDefaults(), defaults);

		Class.$defaults = Cache;

	} else {

		Class.$defaults = SuperDefaults;

	}

});

Jx.Class.setProcessor('declare', 'helpers', function(struct, value){

	Jx.each( struct.helpers, this.__callback_DeclareClassHelpers, struct.Class);

});

Jx.Class.setProcessor('declare', 'onconstruct', function(struct, value){

	this.__help_SetInstanceCallbacks(false, struct, value);

});

Jx.Class.setProcessor('declare', 'ondestruct', function(struct, value){

	this.__help_SetInstanceCallbacks(true, struct, value);

});

/**
 *	Post Declaration Processors
 */
Jx.Class.setProcessor('post', 'singleton', function(struct){

	struct.instance = struct.singleton ?

		this.instantiate( struct.path )

		:

		struct.Class;

});

Jx.Class.setProcessor('post', 'category', function(struct){

	var category = struct.category;

	if (category){

		var Temp = new Function();

		Temp.prototype = struct;

		category = Jx.assign(new Temp(), this.getNsStruct(category));

		category.category = false;

		category.publicize = false;

		category.link = struct;

		this.__ref_ClassMap[ category.path ] = category;

	}

});

Jx.Class.setProcessor('post', '$callback', function(struct, value){

	this.__help_SetAndCascadeCallback(struct, value, 'callback', [ struct.Class, struct.SuperStruct.Class.prototype, struct.instance ]);

});

Jx.Class.setProcessor('post', 'callback', function(struct, value){

	if (Jx.isFunction(value)){

		value.call( struct.Class, struct.SuperStruct.Class.prototype, struct.instance );

	}

});

/**
 *	Pre declare Classes
 */
Jx.Class.declareNsObject('Jx.Class');

/**
 * Exposed Jx methods
 */
Jx.assign(Jx, {

	ns: function(path){

		var J = Jx;

		return J.isString(path) ?

			J.createNamespace(path)

			:

			void(0);

	},

	declare: function(){

		var Mgr = Jx.Class;

		return Mgr.declare.apply(Mgr, arguments);

	},

	categorize: function(){

		var Mgr = Jx.Class;

		return Mgr.declareCategory.apply(Mgr, arguments);

	},

	instantiate: function(Class, args){

		return Jx.Class.instantiate(Class, args);

	},

	instanceOf: function(o, Class){

		var J = Jx;

		if (!J.isFunction(Class)){

			Class = J.Class.getClass(Class);

		}

		return !!Class && o instanceof Class;

	},

	isClass: function(Class, SuperClass){

		var Mgr = Jx.Class;

		Class = Mgr.resolveClass(Class);

		SuperClass = SuperClass ?

			Mgr.resolveClass(Class)

			:

			Object;

		return !!Class && !!SuperClass &&

			(SuperClass === Class || Class.prototype instanceof SuperClass);

	},

	isSingleton: function(path){

		var J = Jx,

			struct = J.isString(path) && J.Class.getStruct(path);

		return !!struct && struct.singleton;

	},

	classExists: function(path){

		var J = Jx;

		return J.isString(path) && J.Class.isDeclared(path);

	},

	resolveClassName: function(Class, DefaultClass){

		var Mgr = Jx.Class;

		return Mgr.isDeclared(Class) ?

			Class

			:

			Mgr.isDeclared(DefaultClass) ?

				DefaultClass

				:

				false;

	},

	getConstructor: function(path){

		var J = Jx;

		return J.isString(path) && J.Class.getClass(path);

	},

	getInstance: function(path){

		var J = Jx;

		return J.isString(path) && J.Class.getInstance(path);

	}

});
